{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-18T06:28:05.816484800Z",
     "start_time": "2024-02-18T06:28:05.796209600Z"
    }
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-18T06:28:06.741714300Z",
     "start_time": "2024-02-18T06:28:06.166783Z"
    }
   },
   "outputs": [],
   "source": [
    "csitrade=pd.read_csv('zz500_2018_2023.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-18T06:28:06.759121Z",
     "start_time": "2024-02-18T06:28:06.745731400Z"
    }
   },
   "outputs": [],
   "source": [
    "#数据一定要按股票排序\n",
    "csitrade['close_r']=csitrade['close']/csitrade['close'].shift(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-18T06:28:07.175260400Z",
     "start_time": "2024-02-18T06:28:07.152432200Z"
    }
   },
   "outputs": [],
   "source": [
    "csitrade.reset_index(inplace=True,drop=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-18T06:28:08.188603700Z",
     "start_time": "2024-02-18T06:28:08.163682800Z"
    }
   },
   "outputs": [],
   "source": [
    "csitrade"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-19T03:56:32.569461200Z",
     "start_time": "2024-02-19T03:56:31.482521800Z"
    }
   },
   "outputs": [],
   "source": [
    "#动量策略\n",
    "import pandas as pd\n",
    "import pickle\n",
    "#trade=pd.read_csv(\"data/DJI/trade.csv\")\n",
    "#train=pd.read_csv(\"data/DJI/train.csv\")\n",
    "#df=pd.concat([train,trade],axis=0)\n",
    "df=csitrade\n",
    "df['ret']=np.nan\n",
    "ins_unique=df['kdcode'].unique()\n",
    "df.rename(columns={'kdcode':'instrument','dt':'datetime'},inplace=True)\n",
    "date_unique=df['datetime'].unique()\n",
    "import datetime\n",
    "from datetime import datetime\n",
    "df['datetime'] = df['datetime'].astype('datetime64')\n",
    "\n",
    "dff_ret=pd.DataFrame()\n",
    "for ins in ins_unique:\n",
    "    df_tic=df[df['instrument']==ins]\n",
    "    df_tic.reset_index(inplace=True)\n",
    "    for i in range(0,len(df_tic)):\n",
    "        if df_tic['datetime'][i]>datetime(2022,1,1):\n",
    "            date=df_tic['datetime'][i]\n",
    "            loc=np.where(date_unique==date)\n",
    "            predate_loc=np.where(date_unique==date)[0][0]-126\n",
    "            date_pre=date_unique[predate_loc]\n",
    "            x=df_tic.loc[df_tic['datetime']==date_pre]['close'].values[0]\n",
    "            yestdaydate_loc=np.where(date_unique==date)[0][0]-1\n",
    "            date_yest=date_unique[yestdaydate_loc]\n",
    "            y=df_tic.loc[df_tic['datetime']==date_yest]['close'].values[0]\n",
    "            df_tic['ret'][i]=(y-x)/x\n",
    "    df_tic.dropna(how='any',inplace=True)\n",
    "    dff_ret=pd.concat([dff_ret,df_tic],axis=0)\n",
    "dff_ret.reset_index(inplace=True)\n",
    "ret_date_unique=dff_ret['datetime'].unique()\n",
    "df_return=pd.DataFrame()\n",
    "#for date in [np.datetime64('2021-1-4'),np.datetime64('2021-6-30')]:\n",
    "#    x_day=dff_ret[dff_ret['datetime']==date]\n",
    "#    r_day=x_day.nsmallest(3,columns='ret').close_r.mean()\n",
    "#    r_day-=x_day.nlargest(3,columns='ret').close_r.mean()\n",
    "day104=dff_ret[dff_ret['datetime']==np.datetime64('2022-01-03')]\n",
    "sma_ins=day104.nsmallest(9,columns='ret').instrument\n",
    "larg_ins=day104.nlargest(9,columns='ret').instrument\n",
    "for date in ret_date_unique:\n",
    "    if date < np.datetime64('2023-01-03'):\n",
    "        x_day=dff_ret[dff_ret['datetime']==date]\n",
    "        r_day=0\n",
    "        for instrument in larg_ins:\n",
    "            one_day=x_day[x_day['instrument']==instrument]['close_r'].values[0]\n",
    "            r_day=r_day+one_day\n",
    "        for instrument in sma_ins:\n",
    "            one_day=x_day[x_day['instrument']==instrument]['close_r'].values[0]\n",
    "            r_day=r_day-1\n",
    "        r_day=r_day/9\n",
    "        b={'datetime':date,'daily_return':r_day}\n",
    "        df_return=df_return.append(b,ignore_index=True)\n",
    "day630=dff_ret[dff_ret['datetime']==np.datetime64('2022-12-30')]\n",
    "sma_ins=day630.nsmallest(9,columns='ret').instrument\n",
    "larg_ins=day630.nlargest(9,columns='ret').instrument\n",
    "for date in ret_date_unique:\n",
    "    if date >= np.datetime64('2023-01-03'):\n",
    "        x_day=dff_ret[dff_ret['datetime']==date]\n",
    "        r_day=0\n",
    "        for instrument in larg_ins:\n",
    "            one_day=x_day[x_day['instrument']==instrument]['close_r'].values[0]\n",
    "            r_day=r_day+one_day\n",
    "        for instrument in sma_ins:\n",
    "            one_day=x_day[x_day['instrument']==instrument]['close_r'].values[0]\n",
    "            r_day=r_day-one_day\n",
    "        r_day=r_day/9\n",
    "        b={'datetime':date,'daily_return':r_day}\n",
    "        df_return=df_return.append(b,ignore_index=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-11-23T15:19:13.066061800Z"
    }
   },
   "outputs": [],
   "source": [
    "(df_return['daily_return']+1).cumprod()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-11-23T15:19:13.069062500Z"
    }
   },
   "outputs": [],
   "source": [
    "#反转策略\n",
    "dff_ret=pd.DataFrame()\n",
    "for ins in ins_unique:\n",
    "    df_tic=df[df['instrument']==ins]\n",
    "    df_tic.reset_index(inplace=True)\n",
    "    for i in range(0,len(df_tic)):\n",
    "        if df_tic['datetime'][i]>datetime(2022,1,1):\n",
    "            date=df_tic['datetime'][i]\n",
    "            loc=np.where(date_unique==date)\n",
    "            predate_loc=np.where(date_unique==date)[0][0]-126\n",
    "            date_pre=date_unique[predate_loc]\n",
    "            x=df_tic.loc[df_tic['datetime']==date_pre]['close'].values[0]\n",
    "            yestdaydate_loc=np.where(date_unique==date)[0][0]-1\n",
    "            date_yest=date_unique[yestdaydate_loc]\n",
    "            y=df_tic.loc[df_tic['datetime']==date_yest]['close'].values[0]\n",
    "            df_tic['ret'][i]=(y-x)/x\n",
    "    df_tic.dropna(how='any',inplace=True)\n",
    "    dff_ret=pd.concat([dff_ret,df_tic],axis=0)\n",
    "dff_ret.reset_index(inplace=True)\n",
    "ret_date_unique=dff_ret['datetime'].unique()\n",
    "df_return=pd.DataFrame()\n",
    "day104=dff_ret[dff_ret['datetime']==np.datetime64('2022-01-03')]\n",
    "sma_ins=day104.nsmallest(9,columns='ret').instrument\n",
    "larg_ins=day104.nlargest(9,columns='ret').instrument\n",
    "for date in ret_date_unique:\n",
    "    if date < np.datetime64('2022-07-01'):\n",
    "        x_day=dff_ret[dff_ret['datetime']==date]\n",
    "        r_day=0\n",
    "        for instrument in larg_ins:\n",
    "            one_day=x_day[x_day['instrument']==instrument]['close_r'].values[0]\n",
    "            r_day=r_day-1\n",
    "        for instrument in sma_ins:\n",
    "            one_day=x_day[x_day['instrument']==instrument]['close_r'].values[0]\n",
    "            r_day=r_day+one_day\n",
    "        r_day=r_day/9\n",
    "        b={'datetime':date,'daily_return':r_day}\n",
    "        df_return=df_return.append(b,ignore_index=True)\n",
    "day630=dff_ret[dff_ret['datetime']==np.datetime64('2022-06-30')]\n",
    "sma_ins=day630.nsmallest(9,columns='ret').instrument\n",
    "larg_ins=day630.nlargest(9,columns='ret').instrument\n",
    "for date in ret_date_unique:\n",
    "    if date >= np.datetime64('2022-07-01'):\n",
    "        x_day=dff_ret[dff_ret['datetime']==date]\n",
    "        r_day=0\n",
    "        for instrument in larg_ins:\n",
    "            one_day=x_day[x_day['instrument']==instrument]['close_r'].values[0]\n",
    "            r_day=r_day-one_day\n",
    "        for instrument in sma_ins:\n",
    "            one_day=x_day[x_day['instrument']==instrument]['close_r'].values[0]\n",
    "            r_day=r_day+one_day\n",
    "        r_day=r_day/9\n",
    "        b={'datetime':date,'daily_return':r_day}\n",
    "        df_return=df_return.append(b,ignore_index=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-11-23T15:19:13.073069Z",
     "start_time": "2023-11-23T15:19:13.072066200Z"
    }
   },
   "outputs": [],
   "source": [
    "df_return"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-11-23T15:19:13.076077100Z"
    }
   },
   "outputs": [],
   "source": [
    "#大盘和日收益率\n",
    "import pandas as pd\n",
    "df_trade=pd.read_csv(\"data/csi300/trade.csv\")\n",
    "df_trade.rename(columns={'stockcode':'instrument','date':'datetime'},inplace=True)\n",
    "df_trade['datetime'] = df_trade['datetime'].astype('datetime64')\n",
    "\n",
    "index_df=pd.read_csv('data/csi300/CSI22index.csv')\n",
    "index_df.rename(columns={'date':'datetime'},inplace=True)\n",
    "index_df['datetime'] = index_df['datetime'].astype('datetime64')\n",
    "#index_df.reset_index(inplace=True)\n",
    "index_date_unique=index_df['datetime'].unique()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2023-11-23T15:19:13.111235200Z",
     "start_time": "2023-11-23T15:19:13.078082Z"
    }
   },
   "outputs": [],
   "source": [
    "df_trade=df_trade[df_trade['datetime']>'2022-02-07']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-11-23T15:19:13.081136200Z"
    }
   },
   "outputs": [],
   "source": [
    "df_trade.reset_index(inplace=True,drop=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-11-23T15:19:13.088155700Z"
    }
   },
   "outputs": [],
   "source": [
    "index_df=index_df[index_df['datetime']>'2022-02-07']\n",
    "index_df.reset_index(inplace=True,drop=True)\n",
    "index_date_unique=index_df['datetime'].unique()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-11-23T15:19:13.090161300Z"
    }
   },
   "outputs": [],
   "source": [
    "df_trade"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-11-23T15:19:13.092166900Z"
    }
   },
   "outputs": [],
   "source": [
    "#deeptrader交易策略\n",
    "dtrader=np.load('deeptrader/NAS/wealth729.npy')\n",
    "dtrader=dtrader.reshape(251)\n",
    "dtrader=pd.DataFrame(dtrader)\n",
    "dtrader.columns=['daily_return']\n",
    "dtrader_return=dtrader/dtrader.shift(1)\n",
    "dtrader_return.fillna(1,inplace=True)\n",
    "df_return['daily_return']=dtrader_return['daily_return']-1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-11-23T15:19:13.094211100Z"
    }
   },
   "outputs": [],
   "source": [
    "#deeppocket交易策略\n",
    "deeppocket=pd.read_csv('deeppocket/NAS/0return.csv')\n",
    "deeppocket['daily_return']=deeppocket['0']/deeppocket['0'].shift(1)\n",
    "deeppocket.fillna(1,inplace=True)\n",
    "df_return['daily_return']=deeppocket['daily_return']\n",
    "df_return['daily_return']=df_return['daily_return']-1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-11-23T15:19:13.096216700Z"
    }
   },
   "outputs": [],
   "source": [
    "df_return"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-11-23T15:19:13.100227700Z"
    }
   },
   "outputs": [],
   "source": [
    "#thgnn\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "df=pd.read_csv('thgnn/nas_pred.csv')\n",
    "df.rename(columns={'dt':'datetime','kdcode':'instrument'},inplace=True)\n",
    "df['datetime']=df['datetime'].astype('datetime64')\n",
    "df_score=pd.DataFrame()\n",
    "for date in index_date_unique[:-1]:\n",
    "    loc=np.where(index_date_unique==date)\n",
    "    nextdate_loc=np.where(index_date_unique==date)[0][0]+1\n",
    "    for i in range(0,len(df)):\n",
    "        if df['datetime'][i]== date:\n",
    "            b={'datetime':index_date_unique[nextdate_loc],'instrument':df['instrument'][i],'score':df['score'][i]}\n",
    "            df_score=df_score.append(b,ignore_index=True)\n",
    "x=pd.merge(df_trade,df_score,on=['datetime','instrument'],how='outer')\n",
    "trade_date_unique=df_trade['datetime'].unique()\n",
    "df_return=pd.DataFrame()\n",
    "b={'datetime':trade_date_unique[0],'daily_return':0}\n",
    "df_return=df_return.append(b,ignore_index=True)\n",
    "for date in trade_date_unique[1:]:\n",
    "    x_day=x[x['datetime']==date]\n",
    "    r_day=x_day.nlargest(9,columns='score').close_r.mean()\n",
    "    r_day=r_day-1\n",
    "    #r_day-=x_day.nsmallest(3,columns='score').close_r.mean()\n",
    "    b={'datetime':date,'daily_return':r_day}\n",
    "    df_return=df_return.append(b,ignore_index=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-18T06:57:42.399464400Z",
     "start_time": "2024-02-18T06:57:41.944613100Z"
    },
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "index_df=pd.read_csv('hs300_2018_2023.csv')\n",
    "index_df.rename(columns={'dt':'datetime'},inplace=True)\n",
    "index_df['datetime'] = index_df['datetime'].astype('datetime64')\n",
    "\n",
    "index_df=index_df[index_df['datetime']>'2022-12-31']\n",
    "index_df.reset_index(inplace=True,drop=True)\n",
    "index_date_unique=index_df['datetime'].unique()\n",
    "\n",
    "df_trade=df_trade[df_trade['datetime']>'2022-12-31']\n",
    "df_trade.reset_index(inplace=True,drop=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-02-18T07:00:36.143686Z",
     "start_time": "2024-02-18T06:58:18.590951200Z"
    }
   },
   "outputs": [],
   "source": [
    "#qlib交易策略\n",
    "import pickle\n",
    "import numpy as np\n",
    "path='TRA/output/hs300/alstm/pred.pkl'\n",
    "f=open(path,'rb')\n",
    "data=pickle.load(f)\n",
    "df=pd.DataFrame(data)\n",
    "#df.reset_index(inplace=True)\n",
    "#df=df[df['datetime']<'2021-12-30']\n",
    "df.reset_index(inplace=True)\n",
    "df_score=pd.DataFrame()\n",
    "#for date in index_date_unique[:-1]:\n",
    "for date in index_date_unique:\n",
    "   # loc=np.where(index_date_unique==date)\n",
    "    #nextdate_loc=np.where(index_date_unique==date)[0][0]+1\n",
    "    for i in range(0,len(df)):\n",
    "        if df['dt'][i]== date:\n",
    "            b={'datetime':date,'instrument':df['kdcode'][i],'score':df['score'][i]}\n",
    "            df_score=df_score.append(b,ignore_index=True)\n",
    "x=pd.merge(df_trade,df_score,on=['datetime','instrument'],how='outer')\n",
    "trade_date_unique=df_trade['datetime'].unique()\n",
    "df_return=pd.DataFrame()\n",
    "#b={'datetime':trade_date_unique[0],'daily_return':0}\n",
    "#df_return=df_return.append(b,ignore_index=True)\n",
    "for date in trade_date_unique:\n",
    "    x_day=x[x['datetime']==date]\n",
    "    r_day=x_day.nlargest(9,columns='score').close_r.mean()\n",
    "    r_day=r_day-1\n",
    "    #r_day-=x_day.nsmallest(9,columns='score').close_r.mean()\n",
    "    b={'datetime':date,'daily_return':r_day}\n",
    "    df_return=df_return.append(b,ignore_index=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-11-23T15:19:13.103233400Z"
    }
   },
   "outputs": [],
   "source": [
    "portfolio_df_performance = df_return.set_index(['datetime'])\n",
    "\n",
    "index_df_performance = index_df.set_index(['datetime'])\n",
    "\n",
    "\n",
    "alpha_df_performance = pd.DataFrame()\n",
    "alpha_df_performance['portfolio_daily_return'] = portfolio_df_performance['daily_return']\n",
    "alpha_df_performance['index_daily_return'] = index_df_performance['daily_return']\n",
    "alpha_df_performance['alpha_daily_return'] = alpha_df_performance['portfolio_daily_return'] - \\\n",
    "                                                alpha_df_performance[\n",
    "                                                    'index_daily_return']\n",
    "alpha_df_performance['portfolio_net_value'] = (alpha_df_performance['portfolio_daily_return'] + 1).cumprod()\n",
    "alpha_df_performance['index_net_value'] = (\n",
    "        alpha_df_performance['index_daily_return'] + 1).cumprod()\n",
    "alpha_df_performance['alpha_net_value'] = (alpha_df_performance['alpha_daily_return'] + 1).cumprod()\n",
    "\n",
    "net_value_columns = ['portfolio_net_value',\n",
    "                        'index_net_value',\n",
    "                        'alpha_net_value']\n",
    "\n",
    "alpha_statistics_df = pd.DataFrame(index=alpha_df_performance[net_value_columns].columns,\n",
    "                                    columns=[\"年化收益\", \"年化波动率\", \"最大回撤率\", \"夏普率\", \"Calmar\", \"IR\", \"月度胜率\"])\n",
    "\n",
    "# alpha_df_performance.set_index(\"dt\", inplace=True)\n",
    "alpha_df_performance.index = pd.to_datetime(alpha_df_performance.index)\n",
    "monthly_statistics_df = alpha_df_performance[net_value_columns].resample('m').last()\n",
    "monthly_statistics_df = pd.concat([alpha_df_performance[:1][\n",
    "                                        ['portfolio_net_value',\n",
    "                                        'index_net_value', 'alpha_net_value']],\n",
    "                                    monthly_statistics_df])\n",
    "monthly_statistics_df = monthly_statistics_df.pct_change()\n",
    "monthly_statistics_df = monthly_statistics_df.dropna()\n",
    "monthly_statistics_df.index = monthly_statistics_df.index.date\n",
    "## TODO 补充第一年的数据\n",
    "yearly_statistics_df = alpha_df_performance[net_value_columns].resample('y').last()\n",
    "yearly_statistics_df = pd.concat([alpha_df_performance[:1][\n",
    "                                        ['portfolio_net_value',\n",
    "                                        'index_net_value', 'alpha_net_value']],\n",
    "                                    yearly_statistics_df])\n",
    "yearly_statistics_df = yearly_statistics_df.pct_change()\n",
    "yearly_statistics_df = yearly_statistics_df.dropna()\n",
    "yearly_statistics_df.index = yearly_statistics_df.index.date\n",
    "\n",
    "alpha_statistics_df.loc[:, \"年化收益\"] = np.mean(\n",
    "    (alpha_df_performance[net_value_columns].tail(1)) ** (252 / len(alpha_df_performance)) - 1)\n",
    "alpha_statistics_df.loc[:, \"年化波动率\"] = np.std(\n",
    "    alpha_df_performance[net_value_columns] / alpha_df_performance[net_value_columns].shift(1) - 1) * np.sqrt(\n",
    "    252)\n",
    "alpha_statistics_df.loc[:, \"累积收益\"] = np.mean(alpha_df_performance[net_value_columns].tail(1) - 1)\n",
    "alpha_statistics_df.loc[:, \"累积波动率\"] = np.std(\n",
    "    alpha_df_performance[net_value_columns] / alpha_df_performance[net_value_columns].shift(1) - 1)\n",
    "alpha_statistics_df.loc[:, \"最大回撤率\"] = np.min(\n",
    "    (alpha_df_performance[net_value_columns] - alpha_df_performance[net_value_columns].cummax()) /\n",
    "    alpha_df_performance[net_value_columns].cummax())\n",
    "alpha_statistics_df.loc[:, \"夏普率\"] = alpha_statistics_df[\"年化收益\"] / alpha_statistics_df[\"年化波动率\"]\n",
    "alpha_statistics_df.loc[:, \"Calmar\"] = alpha_statistics_df[\"年化收益\"] / abs(alpha_statistics_df[\"最大回撤率\"])\n",
    "alpha_statistics_df.loc[:, \"IR\"] = np.mean(\n",
    "    alpha_df_performance[net_value_columns] / alpha_df_performance[net_value_columns].shift(1) - 1) * np.sqrt(\n",
    "    252) / np.std(alpha_df_performance[net_value_columns] / alpha_df_performance[net_value_columns].shift(1) - 1)\n",
    "alpha_statistics_df.loc[:, \"月度胜率\"] = monthly_statistics_df[\n",
    "                                            monthly_statistics_df > 0].count() / monthly_statistics_df.count()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-11-23T15:19:13.104233700Z"
    }
   },
   "outputs": [],
   "source": [
    "alpha_statistics_df"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.10.7 64-bit",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.7"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "beedbe2faf2f7048d727558d0bc3221e7eba2a0b921cac4d4771b2feb8f74b30"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
